﻿using Microsoft.AspNetCore.DataProtection.KeyManagement;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Utilities.Encoders;
using System.Reflection.Metadata;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using XinLife.Core.Helper;
using XinLife.Core.Model;

namespace XinLife.Controllers.Business
{
    /// <summary>
    /// 密码工具类
    /// </summary>
    public class PwdToolController : BaseController
    {

        /// <summary>
        /// 生成key
        /// </summary>
        [HttpGet]
        public AjaxResult Generate([FromQuery] string type)
        {
            if (type == "AES")
            {
                return Success(SecurityUtils.GenerateAesKey());
            }
            else if (type == "RSA")
            {
                var rsa = SecurityUtils.GenerateRSAPublicKeyAndPrivateKey();
                return Success(new
                {
                    cPublicKey = rsa.Item1,
                    cPrivateKey = rsa.Item2
                });
            }
            else if (type == "SM2")
            {
                SM2Util.GenerateKeyHex(out string cPublicKey, out string cPrivateKey);
                return Success(new
                {
                    cPublicKey,
                    cPrivateKey
                });
            }
            else if (type == "SM4")
            {
                SM4Util.GenerateKeyHex(out string cPublicKey, out string cPrivateKey);
                return Success(new
                {
                    cPublicKey,
                    cPrivateKey
                });
            }
            return Success();
        }

        /// <summary>
        /// aes rsa 加密
        /// </summary>
        [HttpPost]
        public AjaxResult Encrypt([FromQuery] string type, [FromForm] string plainText, [FromForm] string key, [FromForm] string publicKey)
        {
            if (type == "AES")
            {
                return Success(SecurityUtils.AesEncrypt(plainText, key));
            }
            else if (type == "RSA")
            {
                return Success(SecurityUtils.RSAEncrypt(plainText, publicKey));
            }
            return Success();
        }
        /// <summary>
        /// aes rsa 解密
        /// </summary>
        [HttpPost]
        public AjaxResult Decrypt([FromQuery] string type, [FromForm] string cipherText, [FromForm] string key, [FromForm] string privateKey)
        {
            if (type == "AES")
            {
                return Success(SecurityUtils.AesDecrypt(cipherText, key));
            }
            else if (type == "RSA")
            {
                return Success(SecurityUtils.RSADecrypt(cipherText, privateKey));
            }
            return Success();
        }


        /// <summary>
        ///散列/哈希 加密
        /// </summary>
        [HttpPost]
        public AjaxResult Encrypt2([FromQuery] string type, [FromForm] string plainText, [FromForm] string hmackey)
        {
            if (type == "SHA1")
            {
                return Success(SecurityUtils.EncryptSHA1(plainText));
            }
            else if (type == "SHA256")
            {
                return Success(SecurityUtils.EncryptSHA256(plainText));
            }
            else if (type == "SHA512")
            {
                return Success(SecurityUtils.EncryptSHA512(plainText));
            }
            else if (type == "MD5")
            {
                return Success(SecurityUtils.EncryptMD5(plainText));
            }
            else if (type == "HmacSHA256")
            {
                return Success(SecurityUtils.EncryptHmacSHA256(plainText, hmackey));
            }
            else if (type == "HmacMD5")
            {
                return Success(SecurityUtils.EncryptHMACMD5(plainText, hmackey));
            }
            return Success();
        }

        /// <summary>
        /// sm2加密
        /// </summary>
        [HttpPost]
        public AjaxResult SM2Encrypt([FromForm] string plainText, [FromForm] string publicKey)
        {
            var handle = new SM2Util(publicKey, "", SM2Util.Mode.C1C3C2);
            var encrypted = handle.Encrypt(Encoding.UTF8.GetBytes(plainText));
            string sign = Hex.ToHexString(encrypted);
            return Success(sign);
        }
        /// <summary>
        /// sm2解密
        /// </summary>
        [HttpPost]
        public AjaxResult SM2Decrypt([FromForm] string cipherText, [FromForm] string privateKey)
        {
            var handle = new SM2Util("", privateKey, SM2Util.Mode.C1C3C2);
            var original = handle.Decrypt(SM2Util.Decode(cipherText));
            string result = Encoding.UTF8.GetString(original);
            return Success(result);
        }


        /// <summary>
        /// sm4加密
        /// </summary>
        [HttpPost]
        public AjaxResult SM4Encrypt([FromForm] string plainText, [FromForm] string key, [FromForm] string iv, [FromForm] string mode)
        {
           
            if (mode == "ECB")
            {
                var encrypted = SM4Util.ECBEncrypt(Encoding.UTF8.GetBytes(plainText), key);
                string base64 = Convert.ToBase64String(encrypted);
                string sign = Hex.ToHexString(encrypted);
                return Success(sign);
            } else if (mode == "CBC")
            {
                var encrypted = SM4Util.CBCEncrypt(Encoding.UTF8.GetBytes(plainText), key, iv);
                string base64 = Convert.ToBase64String(encrypted);
                string sign = Hex.ToHexString(encrypted);
                return Success(sign);
            }
            return Success();
        }
        /// <summary>
        /// sm4解密
        /// </summary>
        [HttpPost]
        public AjaxResult SM4Decrypt([FromForm] string cipherText, [FromForm] string key, [FromForm] string iv, [FromForm] string mode)
        {
            if (mode == "ECB")
            {
                var original = SM4Util.ECBDecrypt(Hex.Decode(cipherText), key);
                string result = Encoding.UTF8.GetString(original);
                return Success(result);
            } else if (mode == "CBC")
            {
                var original = SM4Util.CBCDecrypt(Hex.Decode(cipherText), key, iv);
                string result = Encoding.UTF8.GetString(original);
                return Success(result);
            }
            return Success();
        }
    }
}
